using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.Xna.Framework;
using WPCoco.Tasks;

namespace WPCoco
{
    /// <summary>
    /// Base node of a 2D coordinates system
    /// </summary>
    public class LocalizedNode : Node, ILocalized
    {
        public LocalizedNode()
        {
            Width = Height = 0;
            Position = Vector2.Zero;
            Anchor = Vector2.Zero;
            Scale = new Vector2(1, 1);
            Angle = 0;
        }

        bool isDirty = true;

        protected bool IsDirty
        {
            get { return isDirty; }
            set 
            { 
                isDirty = value;
                if (isDirty)
                    IsDirtySet();
            }
        }

        /// <summary>
        /// Is called when the transformations matrices are not updated
        /// </summary>
        protected virtual void IsDirtySet() { }

        void UpdateMatrix() 
        {
            Matrix a = Matrix.CreateTranslation(-anchor.X * width, -anchor.Y * height, 0);
            Matrix s = Matrix.CreateScale(new Vector3(scale.X, scale.Y, 1));
            Matrix r = Matrix.CreateRotationZ(MathHelper.ToRadians(angle));
            Matrix t = Matrix.CreateTranslation(position.X , position.Y , 0);

            worldViewMatrix = a * s * r * t;

            viewWorldMatrix = Matrix.Invert(worldViewMatrix);

            IsDirty = false;
        }

        Matrix worldViewMatrix = Matrix.Identity;

        /// <summary>
        /// World to View transformation matrix
        /// </summary>
        public Matrix WorldViewMatrix
        {
            get
            {
                if (isDirty)
                    UpdateMatrix();
                return worldViewMatrix;
            }
        }

        Matrix viewWorldMatrix = Matrix.Identity;

        /// <summary>
        /// View to world transformation matrix
        /// </summary>
        public Matrix ViewWorldMatrix
        {
            get 
            {
                if (isDirty)
                    UpdateMatrix();
                return viewWorldMatrix; 
            }
        }

        #region ILocalized Members

        Vector2 position;

        public virtual Vector2 Position
        {
            get
            {
                return position;
            }
            set
            {
                position = value;
                IsDirty = true;
            }
        }

        Vector2 anchor;

        public virtual Vector2 Anchor
        {
            get
            {
                return anchor;
            }
            set
            {
                anchor = value;
                IsDirty = true;
            }
        }

        Vector2 scale;

        public virtual Vector2 Scale
        {
            get
            {
                return scale;
            }
            set
            {
                scale = value;
                IsDirty = true;
            }
        }

        float angle;

        public virtual float Angle
        {
            get
            {
                return angle;
            }
            set
            {
                angle = value;
                IsDirty = true;
            }
        }

        float width;

        public virtual float Width
        {
            get
            {
                return width;
            }
            set
            {
                width = value;
                IsDirty = true;
            }
        }

        float height;

        public virtual float Height
        {
            get
            {
                return height;
            }
            set
            {
                height = value;
                IsDirty = true;
            }
        }

        #endregion

        protected override void BeginDraw(GameTime gameTime)
        {
            WorldMatrix.Shared.Push(WorldViewMatrix);
        }

        protected override void EndDraw(GameTime gameTime)
        {
            WorldMatrix.Shared.Pop();
        }
    }
}
